# coding:utf-8
#########################
#   Author : Lion yu    #
#   Date : 2023/08/15   #
#   Id : SM2772         #
#########################

import threading
import kazoo.client
from handle import Log, zkHost, zkPort

# zkHost = "47.111.73.118"

class CountDownLatch:
    def __init__(self, count):
        self.count = count
        self.condition = threading.Condition()

    def awaits(self):
        try:
            self.condition.acquire()
            while self.count > 0:
                self.condition.wait()
        finally:
            self.condition.release()

    def countDown(self):
        try:
            self.condition.acquire()
            self.count -= 1
            self.condition.notifyAll()
        finally:
            self.condition.release()

    def getCount(self):
        return self.count

class MyZK:
    def __init__(self, hosts=zkHost):
        self.zk = kazoo.client.KazooClient(hosts=hosts, timeout=3)
        self.lockPath = "/locks"
        self.cc = CountDownLatch(1)
        self.zk.start()

    # 获得锁
    def getLock(self, lockname:str):
        self.zk.ensure_path(path=self.lockPath)
        getLocksChildrens = self.zk.get_children(path=self.lockPath)
        if lockname not in getLocksChildrens or len(getLocksChildrens) == 0:
            Log.info(f"{lockname} 锁不存在")
            return True
        else:
            Log.info(f"{lockname} 锁未释放")
            self.cc.countDown()
            return False
        
    # 加锁
    def lock(self,lockname:str):
        try:
            pathName = f"{self.lockPath}/{lockname}"
            locksdata = self.zk.create(path=pathName, makepath=True, value=lockname.encode())
            Log.info(f"{lockname} 锁创建成功 locksdata : {locksdata}")
            return True
        except Exception as e:
            Log.error(f"{lockname} 锁创建失败 {e}")
            return False
    
    # 释放锁
    def release_key(self, lockname:str):
        pathName = f"{self.lockPath}/{lockname}"
        getLocksChildrens = self.zk.get_children(path=self.lockPath)
        if lockname not in getLocksChildrens:
            Log.info(f"locks 下未找到子节点 {lockname} 无需释放")
            return True
        elif lockname in getLocksChildrens:
            self.zk.delete(pathName, recursive=True)
            Log.info(f"释放锁成功 {pathName}")
            return True
        else:
            Log.error(f"释放锁失败 {pathName}")
            return False
    
    def stop(self):
        self.zk.stop()
        return